<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #app {
        width: 1000px;
        height: 500px;
        border: 1px solid #000;
        margin: 0 auto;
        display: flex;
        padding: 20px;
        box-sizing: border-box;
      }

      .leftText,
      .rightText {
        width: 500px;
        border: 1px solid #000;
        padding: 20px;
      }

      p {
        height: 30px;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <div class="leftText">
        <h3>应用场景:对于短时间内连续触发的事件（上面的滚动事件）如滚动事件</h3>
        <p>节流：某一高频事件被触发，在指定的时机间隔内只执行一次</p>
        <p>防抖：某一高频事件不断被触发，仅在最后一次真正执行事件处理代码</p>
      </div>
      <div class="rightText">
        <div>
          <h3>防抖和节流</h3>
          <input type="text" name="" id="" />
        </div>
        <div class="ordinary">
          <h3>普通</h3>
          <p></p>
        </div>
        <div class="debounce">
          <h3>防抖</h3>
          <p></p>
        </div>
        <div class="throttle">
          <h3>节流</h3>
          <p></p>
        </div>
      </div>
    </div>
  </body>
  <script>
    var input = document.querySelector("input");
    var ordinaryTxt = document.querySelector(".ordinary p");
    var debounceTxt = document.querySelector(".debounce p");
    var throttleTxt = document.querySelector(".throttle p");
    input.oninput = (e) => {
      setOrdinaryTxt(e.currentTarget.value);
      setdebounceTxt(e.currentTarget.value);
      setThrottleTxt(e.currentTarget.value);
    };

    // 普通的
    const setOrdinaryTxt = (txt) => {
      ordinaryTxt.innerHTML = txt;
    };

    // 防抖
    // 封装防抖函数
    // cb:回调函数  delay:定时器的时机
    const debounce = (cb, delay = 1000) => {
      // 先定义一个变量 用来保存定时器
      let timeout;
      return (...args) => {
        // 清除未执行的代码，重置回初始化状态
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          // 定时器执行完毕  执行回调函数
          cb(...args);
        }, delay);
      };
    };
    const setdebounceTxt = debounce((txt) => {
      debounceTxt.innerHTML = txt;
    });

    // 节流
    // 封装节流函数
    // cb:回调函数  delay:定时器的时机
    const throttle = (cb, interval = 500) => {
      // 定义 show 为false 方便后面进行判断
      let show = false;
      return (...args) => {
        // 判断是否已空闲，如果在执行中，则直接return，如果空闲，则可以正常触发方法执行。
        if (show) {
          return;
        }
        // 关闭
        show = true;
        // 执行回调函数
        cb(...args);
        setTimeout(() => {
          //执行周期完成后打开阀门，允许再次调用
          show = false;
        }, interval);
      };
    };
    const setThrottleTxt = throttle((txt) => {
      console.log(txt);
      throttleTxt.innerHTML = txt;
    });
  </script>
</html>
